﻿using System.Windows;
using System.Windows.Data;

namespace Sinacor.Infra.UI.Controls.SmartClient.DataGrid
{
	public class DataGridTextColumn : Microsoft.Windows.Controls.DataGridTextColumn, IDataGridColumn
	{
		#region Construtores
		/// <summary>
		/// Construtor estático
		/// </summary>
		static DataGridTextColumn()
		{
			DataGridColumnManager.Initialize(typeof(DataGridTextColumn));
		}
		#endregion

		#region Name
		public static readonly DependencyProperty NameProperty = DataGridColumnManager.NameProperty.AddOwner(typeof(DataGridTextColumn));
		/// <summary>
		/// Nome da coluna
		/// </summary>
		public string Name
		{
			get { return (string)GetValue(NameProperty); }
			set { SetValue(NameProperty, value); }
		}
		#endregion

		#region DataGrid
		/// <summary>
		/// DataGrid para o qual a coluna pertence
		/// </summary>
		public SinacorDataGrid DataGrid
		{
			get { return (SinacorDataGrid)base.DataGridOwner; }
		}
		#endregion

		#region Element Generation
		/// <summary>
		///     Creates the visual tree for text based cells.
		/// </summary>
		protected override FrameworkElement GenerateElement(Microsoft.Windows.Controls.DataGridCell cell, object dataItem)
		{
			SinacorTextBlock textBlock = new SinacorTextBlock();

			SyncProperties(textBlock);

			ApplyStyle(/* isEditing = */ false, /* defaultToElementStyle = */ false, textBlock);
			ApplyBinding(textBlock, SinacorTextBlock.TextProperty);

			return textBlock;
		}

		/// <summary>
		///     Creates the visual tree for text based cells.
		/// </summary>
		protected override FrameworkElement GenerateEditingElement(Microsoft.Windows.Controls.DataGridCell cell, object dataItem)
		{
			// TODO: Gerar SinacorTextBox
			return base.GenerateEditingElement(cell, dataItem);
		}

		private void SyncProperties(FrameworkElement e)
		{
			typeof(Microsoft.Windows.Controls.DataGridTextColumn).InvokeMember("SyncProperties",
				System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance,
				null, this, new object[] { e });
		}

		private void ApplyStyle(bool isEditing, bool defaultToElementStyle, FrameworkElement element)
		{
			typeof(Microsoft.Windows.Controls.DataGridTextColumn).InvokeMember("ApplyStyle",
				System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance,
				null, this, new object[] { isEditing, defaultToElementStyle, element });
		}

		private void ApplyBinding(DependencyObject target, DependencyProperty property)
		{
			typeof(Microsoft.Windows.Controls.DataGridTextColumn).InvokeMember("ApplyBinding",
				System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance,
				null, this, new object[] { target, property });
		}

		#endregion

		#region SortIndex
		public static readonly DependencyProperty SortIndexProperty = DataGridColumnManager.SortIndexProperty.AddOwner(typeof(DataGridTextColumn));
		/// <summary>
		/// Ordem que a coluna foi ordenada
		/// </summary>
		public int SortIndex
		{
			get { return (int)GetValue(SortIndexProperty); }
			protected set { SetValue(DataGridColumnManager.SortIndexKey, value); }
		}
		#endregion

		#region HorizontalCellAlignment
		public static readonly DependencyProperty HorizontalCellAlignmentProperty = DataGridColumnManager.HorizontalCellAlignmentProperty.AddOwner(typeof(DataGridTextColumn));
		/// <summary>
		/// Alinhamento horizontal do conteúdo da célula
		/// </summary>
		public HorizontalAlignment HorizontalCellAlignment
		{
			get { return (HorizontalAlignment)GetValue(HorizontalCellAlignmentProperty); }
			set { SetValue(HorizontalCellAlignmentProperty, value); }
		}
		#endregion

		#region VerticalCellAlignment
		public static readonly DependencyProperty VerticalCellAlignmentProperty = DataGridColumnManager.VerticalCellAlignmentProperty.AddOwner(typeof(DataGridTextColumn));
		/// <summary>
		/// Alinhamento vertical do conteúdo da célula
		/// </summary>
		public VerticalAlignment VerticalCellAlignment
		{
			get { return (VerticalAlignment)GetValue(VerticalCellAlignmentProperty); }
			set { SetValue(VerticalCellAlignmentProperty, value); }
		}
		#endregion

		#region CanUserChangeVisibility
		public static readonly DependencyProperty CanUserChangeVisibilityProperty = DataGridColumnManager.CanUserChangeVisibilityProperty.AddOwner(typeof(DataGridTextColumn));
		/// <summary>
		/// Indica se o usuário pode alterar a visibilidade da coluna
		/// </summary>
		public bool CanUserChangeVisibility
		{
			get { return (bool)GetValue(CanUserChangeVisibilityProperty); }
			set { SetValue(CanUserChangeVisibilityProperty, value); }
		}
		#endregion

		#region Excel

		#region CanUserExportExcel
		public static readonly DependencyProperty CanUserExportExcelProperty = DataGridColumnManager.CanUserExportExcelProperty.AddOwner(typeof(DataGridTextColumn));
		/// <summary>
		/// Indica se a coluna permite ser exportada para Excel
		/// </summary>
		public bool CanUserExportExcel
		{
			get { return (bool)GetValue(CanUserExportExcelProperty); }
			set { SetValue(CanUserExportExcelProperty, value); }
		}
		#endregion

		#region ExcelContentBinding
		private BindingBase _excelContentBinding = null;
		/// <summary>
		/// Binding do valor a ser exportado para o Excel
		/// </summary>
		public BindingBase ExcelContentBinding
		{
			get
			{
				return _excelContentBinding ?? this.Binding;
			}
			set
			{
				_excelContentBinding = value;
			}
		}
		#endregion

		#endregion

		#region PropertyChanged
		protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
		{
			base.OnPropertyChanged(e);
			DataGridColumnManager.PropertyChanged(this, e);
		}
		#endregion

		public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
		void IDataGridColumn.TriggerPropertyChanged(string propertyName)
		{
			if (PropertyChanged != null)
				PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
		}
	}
}